using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class 区块加载控制器 : 单例_基础管理器<区块加载控制器>
{
    public int 区块大小 = 10;
    public int 区块半径 = 4; //1,2,3,4,5 将以增加周围直径区块

    public int 植物区块大小 = 5;
    public int 植物区块半径 = 5;

    //上述属性可根据设备性能修改数值


    Vector2Int 计算结束坐标(Vector2Int 区块开始坐标,int 区块大小)
    {
        return new Vector2Int(区块开始坐标.x + 区块大小-1, 区块开始坐标.y + 区块大小-1);//防止与起始坐标重复
    }
    List<Vector2Int> 获取周围坐标(int 半径, int 区块大小, Vector2Int pos)
    {
        List<Vector2Int> ls = new List<Vector2Int>();

        for (int x = -半径; x <= 半径+1; x++)
        {
            for (int y = -半径; y <= 半径+1; y++)
            {
                ls.Add(new Vector2Int(pos.x + x * 区块大小, pos.y + y * 区块大小));
            }
        }
        return ls;
    }

    List<Vector2Int> 上次的区块开始坐标 = new List<Vector2Int>();
    Vector2Int 上一次的区块;

    IEnumerator _加载区块(Vector2 pos)
    {
        int x = (int)(pos.x / 区块大小) * 区块大小;
        int y = (int)(pos.y / 区块大小) * 区块大小;

        Vector2Int 当前区块 = new Vector2Int(x, y);

        if (上一次的区块 == 当前区块)//如果还是当前区块,将跳过加载
        { 
            完成 = true;
            yield break;
        }
        else if ((当前区块 - 上一次的区块).magnitude<= 区块大小 * 3)
        {
            完成 = true;
            yield break;
        }
        
        上一次的区块 = 当前区块;

        List<Vector2Int> 周围区块 = 获取周围坐标(区块半径, 区块大小, 当前区块);
        foreach (var lsPos in 周围区块)
        {
            if (!上次的区块开始坐标.Contains(lsPos))//如果不存在,将生成瓦片
            {
                上次的区块开始坐标.Add(lsPos);
                Vector2Int 结束 = 计算结束坐标(lsPos, 区块大小);
                //生成地形
                for (int x1 = lsPos.x; x1 <= 结束.x; x1++)
                {
                    for (int y1 = lsPos.y; y1 <= 结束.y; y1++)
                    {
                        Vector2Int 具体坐标 = new Vector2Int(x1, y1);
                        地图物品 地皮 = 地图数据管理器.获取实例.读取瓦片(具体坐标, 图层.底层);
                        if (地皮 == null)
                            瓦片管理器.获取实例.设置瓦片(具体坐标, 游戏数据管理器.获取实例.获取地图模板("边界"), 图层.底层);
                        else
                            瓦片管理器.获取实例.设置瓦片(具体坐标, 地皮, 图层.底层);


                        瓦片管理器.获取实例.设置瓦片(具体坐标, 地图数据管理器.获取实例.读取瓦片(具体坐标, 图层.中层), 图层.中层);
                        瓦片管理器.获取实例.设置瓦片(具体坐标, 地图数据管理器.获取实例.读取瓦片(具体坐标, 图层.上层), 图层.上层);
                    }
                }
                yield return 0;
            }
        }

        List<Vector2Int> 移除 = new List<Vector2Int>();
        foreach (var item in 上次的区块开始坐标)
            if (!周围区块.Contains(item))
                移除.Add(item);

        foreach (var item in 移除)
        {
            Vector2Int 结束 = 计算结束坐标(item, 区块大小);
            //生成地形
            for (int x1 = item.x; x1 <= 结束.x; x1++)
            {
                for (int y1 = item.y; y1 <= 结束.y; y1++)
                {
                    Vector2Int 具体坐标 = new Vector2Int(x1, y1);
                    瓦片管理器.获取实例.设置瓦片(具体坐标, null,图层.全部);
                }
            }
            yield return 0;
        }

        foreach (var item in 移除)
            上次的区块开始坐标.Remove(item);

        完成 = true;
    }
    Vector2Int 植物的上一次区块;
    List<Vector2Int> 上次的植物区块开始坐标 = new List<Vector2Int>();

    IEnumerator _加载植物(Vector2 pos)
    {
        int x = (int)(pos.x / 植物区块大小) * 植物区块大小;
        int y = (int)(pos.y / 植物区块大小) * 植物区块大小;

        Vector2Int 当前区块 = new Vector2Int(x, y);

        if (植物的上一次区块 == 当前区块)//如果还是当前区块,将跳过加载
        {
            植物完成 = true;
            yield break;
        }
        else if ((当前区块 - 植物的上一次区块).magnitude<= 植物区块大小 * 1)
        {
            植物完成 = true;
            yield break;
        }

        植物的上一次区块 = 当前区块;

        List<Vector2Int> 周围区块 = 获取周围坐标(植物区块半径, 植物区块大小, 当前区块);

        foreach (var lsPos in 周围区块)
        {
            if (!上次的植物区块开始坐标.Contains(lsPos))
            {
                上次的植物区块开始坐标.Add(lsPos);
                Vector2Int 结束 = 计算结束坐标(lsPos, 植物区块大小);
                for (int x1 = lsPos.x; x1 <= 结束.x; x1++)
                {
                    for (int y1 = lsPos.y; y1 <= 结束.y; y1++)
                    {
                        Vector2Int 具体坐标 = new Vector2Int(x1, y1);
                        实例化植物控制器.获取实例.实例化道具(具体坐标);
                    }
                }
            }
        }


        List<Vector2Int> 移除 = new List<Vector2Int>();
        foreach (var item in 上次的植物区块开始坐标)
            if (!周围区块.Contains(item))
                移除.Add(item);

        foreach (var item in 移除)
        {
            Vector2Int 结束 = 计算结束坐标(item, 植物区块大小);
            //生成地形
            for (int x1 = item.x; x1 <= 结束.x; x1++)
            {
                for (int y1 = item.y; y1 <= 结束.y; y1++)
                {
                    Vector2Int 具体坐标 = new Vector2Int(x1, y1);
                    实例化植物控制器.获取实例.回收道具(具体坐标);
                }
            }
            yield return 0;
        }

        foreach (var item in 移除)
            上次的植物区块开始坐标.Remove(item);

        植物完成 = true;
    }

    private bool 完成 = true;
    private bool 植物完成 = true;
    public void 加载区块(Vector2 pos)
    {
        //判断在哪一个区块
        if (完成)
        {
            完成 = false;
            帧更新控制器.获取实例.开启携程(_加载区块(pos));
        }
        if (植物完成)
        {
            植物完成 = false;
            帧更新控制器.获取实例.开启携程(_加载植物(pos));
        }
    }
}
